module PhyRegStateTable(
	
	input			i_PRST_clk,
	input			i_PRST_enable,
	input			i_PRST_reset,
	//FreeReg
	output	[5:0]	o_PRST_FreeReg1,
	output	[5:0]	o_PRST_FreeReg2,
	//trans
	input	[11:0]	i_PRST_Mappped,
	input	[35:0]	i_PRST_Executed,
	input	[11:0]	i_PRST_Assigned,
	input	[11:0]	i_PRST_Free,
	input			i_PRST_rollback,
	//PhyRegState
	output	[63:0]	o_PRST_PhyRegState
	
);

	reg		[1:0]	PhyRegState[63:0]
	
	wire	[63:0]	FreeList;
	begin:	freelist
		reg	[7:0]	tempI;
		for(tempI=8'd0; tempI<=8'd63; tempI=tempI+8'd1)
			assign	FreeList[tempI[5:0]] = (PhyRegState[tempI[5:0]]==2'd0);
	end
	
	wire	[63:0]	lowbit = (~FreeList + 64'd1) & FreeList;
	wire	[63:0]	secbit = (~(FreeList-lowbit) + 64'd1) & (FreeList-lowbit);
	
LeadingOneCount64 PRST_LOC64_freereg1(
	.i_LOC64_datain(lowbit),
	.o_LOC64_vld(	),
	.o_LOC64_cnt(	o_PRST_FreeReg1)
);

LeadingOneCount64 PRST_LOC64_freereg2(
	.i_LOC64_datain(secbit),
	.o_LOC64_vld(	),
	.o_LOC64_cnt(	o_PRST_FreeReg2)
);
	
	wire	[63:0]	AvailableList;
	begin:	availablelist
		reg	[7:0]	tempJ;
		for(tempJ=8'd0; tempJ<=8'd63; tempJ=tempJ+8'd1)
			assign	AvailableList[tempJ[5:0]] = (PhyRegState[tempJ[5:0]]==2'b10 | PhyRegState[tempJ[5:0]]==2'b11);
	end
	assign	o_PRST_PhyRegState = AvailableList;
	
	wire	[5:0]	Map1 = i_PRST_Mappped[5:0];
	wire	[5:0]	Map2 = i_PRST_Mappped[11:6];
	wire	[5:0]	Ass1 = i_PRST_Assigned[5:0];
	wire	[5:0]	Ass2 = i_PRST_Assigned[11:6];
	wire	[5:0]	Free1 = i_PRST_Free[5:0];
	wire	[5:0]	Free2 = i_PRST_Free[11:6];
	
	wire	[5:0]	Exe1 = i_PRST_Executed[5:0];
	wire	[5:0]	Exe2 = i_PRST_Executed[11:6];
	wire	[5:0]	Exe3 = i_PRST_Executed[17:12];
	wire	[5:0]	Exe4 = i_PRST_Executed[23:18];
	wire	[5:0]	Exe5 = i_PRST_Executed[29:24];
	wire	[5:0]	Exe6 = i_PRST_Executed[35:30];
	
always @(posedge i_PRST_clk)
	begin
		if(i_PRST_reset)
			begin:	reset
				reg	[7:0]	tempK;
				for(tempK=8'd0; tempK<=8'd31; tempK=tempK+8'd1)
					PhyRegState[tempK[5:0]] <= 2'b11;
				reg	[7:0]	tempL;
				for(tempL=8'd32; tempL<=8'd63; tempL=tempL+8'd1)
					PhyRegState[tempL[5:0]] <= 2'b00;
			end
		else if(i_PRST_enable)
			begin
				if(i_PRST_rollback)
					begin:	rollback
						reg	[7:0]	tempn;
						for(tempn=8'd0; tempn<=8'd63; tempn=tempn+8'd1)
							if(PhyRegState[tempn[5:0]]!=2'b11) PhyRegState[tempn[5:0]] <= 2'b00;
					end
				else
					begin
						if(Map1) PhyRegState[Map1] <= 2'b01;
						if(Map2) PhyRegState[Map2] <= 2'b01;
						if(Ass1) PhyRegState[Ass1] <= 2'b11;
						if(Ass2) PhyRegState[Ass2] <= 2'b11;
						if(Free1) PhyRegState[Free1] <= 2'b00;
						if(Free2) PhyRegState[Free2] <= 2'b00;
						
						if(Exe1) PhyRegState[Exe1] <= 2'b10;
						if(Exe2) PhyRegState[Exe2] <= 2'b10;
						if(Exe3) PhyRegState[Exe3] <= 2'b10;
						if(Exe4) PhyRegState[Exe4] <= 2'b10;
						if(Exe5) PhyRegState[Exe5] <= 2'b10;
						if(Exe6) PhyRegState[Exe6] <= 2'b10;
					end
			end
	end

endmodule